﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.Practices.Unity;
using Codeplex.Unity.AutoRegister.Config;

namespace Codeplex.Unity.AutoRegister.Test
{
    [TestClass]
    public class AutoRegisterExtensionTest
    {
        private UnityContainer container;
        private AutoRegistExtension extension;

        [TestInitialize]
        public void SetUp()
        {
            this.container = new UnityContainer();
            this.container.AddNewExtension<AutoRegistExtension>();
            this.extension = this.container.Configure<AutoRegistExtension>();
        }

        [TestCleanup]
        public void TearDown()
        {
            this.container.Dispose();
            this.container = null;
            this.extension = null;
        }

        [TestMethod]
        public void Config()
        {
            this.extension.IsNotNull();
        }

        [TestMethod]
        public void ArgumentNullExceptionTest()
        {
            AssertEx.Throws<ArgumentNullException>(() => this.extension.AddProvider(null));
        }

        [TestMethod]
        public void RegistTest()
        {
            this.extension.AddProvider(new TestProvider());
            var def = this.container.Resolve<DefaultType>();
            def.IsNotNull();
            def.IsNotSameReferenceAs(this.container.Resolve<DefaultType>());

            var custom = this.container.Resolve<Base>("Base");
            custom.IsNotNull();
            custom.IsInstanceOf<CustomType>();
            custom.IsSameReferenceAs(this.container.Resolve<Base>("Base"));
            custom.Name.Is("tanaka");
        }

        class Base 
        {
            public string Name { get; set; }
        }
        [UnityExport]
        class DefaultType : Base { }

        [UnityExport(FromType = typeof(Base), 
            Name = "Base", 
            LifetimeManager = typeof(ContainerControlledLifetimeManager),
            InjectionMemberProvider = typeof(TestInjectionMemberProvider))]
        class CustomType : Base 
        {
        }

        class TestProvider : RegistTypeTraitProvider
        {
            protected override IEnumerable<Type> GetTypes()
            {
                yield return typeof(DefaultType);
                yield return typeof(CustomType);
            }

            protected override IEnumerable<RegistTypeTrait> BuildTrait(Type type)
            {
                return AnnotationRegistTypeTraitBuilder.Build(type);
            }
        }

        class TestInjectionMemberProvider : InjectionMemberProvider
        {
            public override IEnumerable<InjectionMember> GetInjectionMembers()
            {
                // Nameプロパティにtanakaと入力する
                return new[]
                {
                    new InjectionProperty("Name", "tanaka")
                };
            }
        }


    }
}
